package lib.rpc;

import java.io.IOException;
import java.util.List;

import lib.messaging.NetworkAddress;
import lib.paxos.AcceptMessage;
import lib.paxos.AckMessage;
import lib.paxos.DecideMessage;
import lib.paxos.PaxosException;
import lib.paxos.PrepareMessage;
import lib.paxos.SyncMessage;

/**
 * Interface for the various RPC methods that can be invoked
 *
 * @author abhip
 *
 */
public interface IRPCMethods {
    static final String AcceptMethodName = "Accept";
    static final String AppendLineToFileMethodName = "AppendLineToFile";
    static final String CreateFileMethodName = "CreateFile";

    static final String DecideMethodName = "Decide";
    static final String GetLineFromFileMethodName = "GetLineFromFile";
    static final String JoinMethodName = "Join";
    // Paxos related RPC methods
    static final String PrepareMethodName = "Prepare";
    static final String ReconfigureMethodName = "Reconfigure";
    static final String SyncMethodName = "Sync";

    AckMessage Accept(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            AcceptMessage acceptMsg)
                    throws ClassNotFoundException, IOException, PaxosException;

    /**
     * RPC method to append data to a file on server
     * @param clientAddress
     * @param serverAddress
     * @param fileName
     * @param data
     * @throws ClassNotFoundException
     * @throws IOException
     */
    void AppendLineToFile(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            int roundID,
            String fileName,
            String data) throws ClassNotFoundException, IOException;

    /**
     * RPC method to create a file on server
     * @param clientAddress
     * @param serverAddress
     * @param fileName
     * @throws ClassNotFoundException
     */
    void CreateFile(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            int roundID,
            String fileName) throws IOException, ClassNotFoundException;

    AckMessage Decide(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            DecideMessage decideMessage)
                    throws ClassNotFoundException, IOException, PaxosException;

    /**
     * RPC methods to read a particular line from a file on server
     * @param clientAddress
     * @param serverAddress
     * @param fileName
     * @param lineNumber
     * @return line read
     * @throws IOException
     * @throws ClassNotFoundException
     */
    String GetLineFromFile(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            int roundID,
            String fileName,
            int lineNumber) throws ClassNotFoundException, IOException;

    List<NetworkAddress> Join(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            int roundID,
            NetworkAddress newServerAddress) throws ClassNotFoundException, IOException;
    
    AckMessage Prepare(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            PrepareMessage prepareMsg)
                    throws ClassNotFoundException, IOException, PaxosException;

    void Reconfigure(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            int roundID,
            List<NetworkAddress> newServerAddresses) throws ClassNotFoundException, IOException;
    
    AckMessage Sync(
            NetworkAddress clientAddress,
            NetworkAddress serverAddress,
            SyncMessage syncMessage)
                    throws ClassNotFoundException, IOException, PaxosException;
}
